<?php

namespace App\Models\Post;

use App\Libraries\Easemob\Easemob;
use App\Libraries\Tools\Constants;
use App\Libraries\Tools\ConstVar;
use App\Libraries\Tools\URL;
use App\Models\BaseModel;
use App\Models\Order\Order;
use App\Models\User\Follow;
use App\Models\User\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class Post extends BaseModel
{

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'status',
        'post',
        'images',
        'free',
        'price',
        'consumed_at',
        'shop',
        'address',
        'contact',
        'consumption',
        'need_auth',
        'is_public',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'need_auth',
        'income_status',
    ];

    protected $dateFormat = 'U';
    protected $cur_user_id;


    /**
     * 关联用户信息
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user(){
        return $this->belongsTo('App\Models\User\User', 'user_id', 'user_id');
    }

    /**
     * 关联转发的帖子
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function repost(){
        return $this->hasOne('App\Models\Post\PostDetail', 'id', 'repost_id');
    }

    /**
     * 关联购买记录
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function purchase(){
        return $this->hasMany('App\Models\Post\PostPurchase', 'post_id', 'id')->where('user_id', $this->cur_user_id)->where('status', 1);
    }

    /**
     * 关联转帖购买记录
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function repost_purchase(){
        return $this->hasMany('App\Models\Post\PostPurchase', 'post_id', 'repost_id')->where('user_id', $this->cur_user_id);
    }

    /**
     * 关联统计数据
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function statistic(){
        return $this->hasOne('App\Models\Post\PostSta', 'post_id', 'id');
    }

    /**
     * 关联收藏数据
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function fav(){
        return $this->hasOne('App\Models\Post\PostFav', 'post_id', 'id')->where('user_id', $this->cur_user_id);
    }

    /**
     * 关联点赞数据
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function praise(){
        return $this->hasOne('App\Models\Post\PostPraise', 'post_id', 'id')->where('user_id', $this->cur_user_id);
    }

    /**
     * 关联积分
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function points(){
        return $this->hasOne('App\Models\User\UserPoint', 'user_id', 'user_id');
    }

    /**
     * 关联商家
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function shop(){
        return $this->hasOne('App\Models\Shop\Shop', 'shop_id', 'shop_id');
    }

    /**
     * 获取所有post
     * @param $cur_user_id
     * @param Request $request
     * @return array
     */
    public function getPosts( $cur_user_id, Request $request){
        $this->cur_user_id = $cur_user_id;
        $data = [];
        $sql = $this->select('posts.*')->selectRaw('if(follow.id,1,0) as is_follow')
            ->rightJoin('users',function($join) {
                $join->on('posts.user_id', '=', 'users.user_id')->where('users.status', 1);
            })
            ->withOnly('user', ['user_id', 'nickname', 'cover', 'vip_level'])
            ->withOnly('shop', ['shop_id', 'title', 'address', 'cover'])
            ->with(['repost' => function($query) use($cur_user_id){
                $query->select('post_detail.*')
                    ->selectRaw('if(follow.id,1,0) as is_follow')
                    ->leftJoin('follow', function($join) use($cur_user_id){
                        $join->on('follow.follow_id', '=', 'post_detail.user_id')->where('follow.user_id', $cur_user_id)->where('follow.status', 1);
                    });
            }])
            ->with(['purchase' => function($query) use($cur_user_id){
                $query->where('user_id', $cur_user_id);
            }])
            ->with(['repost_purchase' => function($query) use($cur_user_id){
                $query->where('user_id', $cur_user_id);
            }])
            ->with('statistic')
            ->with('fav')
            ->with('praise')
            ->with('points')
            ->leftJoin('follow', function($join) use($cur_user_id){
                $join->on('follow.follow_id', '=', 'posts.user_id')->where('follow.user_id', $cur_user_id)->where('follow.status', 1);
            });
        if(!empty($request['city_id'])){
            $sql = $sql->where('posts.city_id', $request['city_id']);
        }
        if(!empty($request['district_id'])){
            $sql = $sql->where('posts.district_id', $request['district_id']);
        }
        if(!empty($request['category'])){
            $sql = $sql->where('posts.category', $request['category']);
        }
        if(!empty($request['shop_ids'])){
            $sql = $sql->whereIn('posts.shop_id', json_decode($request['shop_ids'], true));
        }
        switch($request['type']){
            case 0://最新
                $sql = $sql->where('posts.repost_id', 0)->where('posts.is_public', 1);
                break;
            case 1://已购买
                $purchase = new PostPurchase();
                $bought_post = $purchase->select('post_id')->where('user_id', $cur_user_id)->where('status', 1)->get()->toArray();
                $sql = $sql->whereIn('posts.id', $bought_post)
                    ->where('posts.repost_id', 0);
                break;
            case 2://收藏
                $sql = $sql->rightJoin('post_fav', function($join)use($cur_user_id){
                    $join->on('post_fav.post_id', '=', 'posts.id')->where('post_fav.status', 1)->where('post_fav.user_id', $cur_user_id);
                });
                break;
            case 3://离我最近
                $distance_const = Constants::$DISTANCE_CONST;
                $sql = $sql->orderBy(DB::raw("(ST_DISTANCE(POINT(posts.longitude, posts.latitude),POINT({$request['lng']}, {$request['lat']}))*{$distance_const})"), 'asc')
                    ->where('posts.longitude', '<>', 0)
                    ->where('posts.latitude', '<>', 0)
                    ->where('posts.repost_id', 0)
                    ->where('posts.is_public', 1);
                break;
            case 4://最热
                $sql = $sql->leftJoin('post_sta', 'posts.id', '=', 'post_sta.post_id')
                    ->orderBy('post_sta.comment', 'desc')
                    ->orderBy('post_sta.view', 'desc')
                    ->where('posts.created_at', '>=', time()-86400*30)
                    ->where('posts.repost_id', 0)
                    ->where('posts.is_public', 1);
                break;
            case 5://关键字搜索
                $sql = $sql->havingRaw("match(posts.post) against ('*{$request['keyword']}*' IN BOOLEAN MODE)")
                    ->where('posts.repost_id', 0);
                break;
            case 6://关注
                $follow = new Follow();
                $followed_users = $follow->select('follow_id')->where('user_id', $cur_user_id)->where('status', 1)->get()->toArray();
                $sql = $sql->whereIn('posts.user_id', $followed_users);
                break;
            case 7://特定用户
                $sql = $sql->where('posts.user_id', $request['user_id']);
                break;
            default:
                $sql = $sql->where('posts.repost_id', 0)
                    ->where('posts.is_public', 1);
        }
        $data['list'] = $sql->where('posts.status', 1)
            ->whereRaw("posts.user_id NOT IN (SELECT black_id FROM black_lists WHERE user_id='{$cur_user_id}' AND status=1)")
            ->forPage($request['page'], $request['size']+1)
            ->orderBy('posts.posted_at', 'desc')
            ->get()
            ->toArray();
//        Log::debug($sql->toSql());
        $data['next_page'] = $request['page'] + 1;
        $data['page_size'] = $request['size'];
        return $this->after($data);
    }

    /**
     * 帖子详情
     * @param $id
     * @param $cur_user_id
     * @return array
     */
    public function detail($id, $cur_user_id){
        $this->cur_user_id = $cur_user_id;
        $data = $this->withOnly('user', ['user_id', 'nickname', 'cover', 'vip_level'])
            ->with('repost')
            ->with('purchase')
            ->with('repost_purchase')
            ->with('statistic')
            ->with('fav')
            ->with('praise')
            ->with('points')
            ->where('status', 1)
            ->where('id', $id)
            ->first();
        return $this->after($data);
    }

    /**
     * 购买帖子前的检查
     * @param Request $request
     * @param PostPurchase $postPurchase
     * @return array
     */
    public function beforeCheck(Request $request, PostPurchase $postPurchase){
        $user = Auth::user();
        if($user->vip_level){
            $this->rs_format['code'] = 40001;
            return $this->rs_format;
        }

        $post = $this->where('id', $request['id'])->where('status', 1)->first();
        if(empty($post)){
            $this->rs_format['code'] = 40101;
            return $this->rs_format;
        }
        if(empty($post->price)){
            $this->rs_format['code'] = 40001;
            return $this->rs_format;
        }

        $postPurchase = $postPurchase->where('user_id', $user->user_id)
            ->where('post_id', $request['id'])
            ->where('status', 1)
            ->first();
        if($postPurchase){
            $this->rs_format['code'] = 40001;
            return $this->rs_format;
        }

        $order = Order::where('user_id', $user->user_id)->where('type', ConstVar::$ORDER_TYPE_POST)
            ->where('object_id', $request['id'])->whereIn('status', [0,1])
            ->first();
        if($order && $order->status == 1){
            $this->rs_format['code'] = 40001;
            return $this->rs_format;
        }elseif($order && $order->status == 0){
            $order->status = 7;
            $order->save();
        }
        $this->rs_format['data']['price'] = $post->price;
        $this->rs_format['data']['body'] = '购买主题';
        $this->rs_format['data']['ext_id'] = $post->user_id;
        return $this->rs_format;
    }
}
